// 字面量
// 也可以直接使用字面量进行类型声明，限制当前变量值为不可修改
let a: 10
a = 10
// a = 11    // 报错
// 使用场景,使用|连接多个类型(联合类型)
let b: "male" | "female"
let c: boolean | string
c = true
c = "hello"

// any 表示任意类型，一个变量设置类型为any后相当于对该变量关闭了TS的类型检测
// 使用TS时，不建议使用any类型
let d: any // 显式any
// let d   // 隐式any
d = 10
d = 'hello'
d = true

// unknown 表示未知类型的值
let e: unknown
e = 10
e = 'hello'
e = true

let s: string
//d的类型时any，它可以赋值给任意变量
s = d

// 变量e为unknown，下方s报错，s为string
// e = 'hello'
// s = e
// unknown 实际上就是一个类型安全的any
// unknown类型的变量，不能直接复制给其他变量
// 解决方式，类型判断
if (typeof e === "string") {
    s = e
}
// 或 类型断言 (告诉解析器变量的实际类型)
s = e as string
s = <string>e

// void 表示函数无返回值
function fnSee(): void {

}

function fn2() {

}

function fn(num) {
    if (num === 0) {
        return 123
    } else if (num === '123') {
        return "123"
    } else {
        return true
    }
}

// never 表示永远不会返回结果
function fnNev(): never {
    throw new Error('报错了')
}

// object 表示一个JS对象
let z: object
z = {}
z = function () {
}
// {}用来指定对象中可以包含哪些属性
// 语法：{属性名：属性值……}
// 需注意这种写法，个数也会被限制,age?表示可选属性
let zi: {
    name: string,
    age?: number
}
zi = {name: "123"}
// [propName: string](任意属性名): any(任意类型)
let zxc: { name: string, [propName: string]: any }
zxc = {
    name: '猪八戒',
    a: 1,
    b: 2
}
// 设置函数结构的类型声明
let zx: (a: number, b: number) => number
zx = function (n1, n2): number {
    return n1 + n2
}
// 以下代码报错
// zx = function (n1:string, n2): number {
//     return n1 + n2
// }

// 数组Array
// string[] 表示字符串数组
let as: string[]
as = ['1', '2', '3']
let sd: number[]
// ==
let qw: Array<number>

// tuple 固定长度数组，TS中新增类型
let rt: [string, number]
rt = ['a', 2]

// enum 枚举，TS中新增类型
enum Gender {
    Male,
    Female
}

let gh: { name: string, gender: Gender }
gh = {
    name: '孙悟空',
    gender: Gender.Male
}

console.log(gh.gender === Gender.Male)

// &表示同时
let j: { name: string } & { age: number }
j = {
    name: '123',
    age: 123
}

// 类型的别名
type myType = string
let m: myType
type youType = 1 | 2 | 3 | 4 | 5
let y: youType
let l: youType









